#include "awp1921.h"
#include "awp1921_wave.h"


I2C_HandleTypeDef I2C_Handle;

static AWP1921_Common_Confg g_Common_Config =
{
    AWP1921_ADC_GAIN_FULL_SCALE_95V,
    AWP1921_ADC_OUT_POSITIVE_POLARITY,
    AWP1921_ADC_CALIBE_ENABLE,
    AWP1921_AMPLITUDE_59400_MV,
    AWP1921_DAC_SAMPLE_RATA_9US
};

static const AWP1921_Sense_Play_Config g_Sensor_Play_Config0 =
{
    AWP1921_SLICE_NUMBER_1,
    AWP1921_ADC_OVER_H_EN
};


static AWP1921_ADC_Config g_ADC_Config =
{
    AWP1921_ADC_AUTO_MODE,
    AWP1921_ADC_AVERAGE_TIME_0,
    AWP1921_ADC_OVV_1023_TIMES,
    AWP1921_ADC_THRESHOLD_HIGH_3V,
    AWP1921_ADC_THRESHOLD_LOW_3V, //下阈值暂时未被使用
    {
        {
            AWP1921_SLICE_NUMBER_1,
            AWP1921_ADC_OVER_H_EN
        },
    }

};

/* slice0用于SRAM播放, slice1用于ADC采样 sense播放 */
static AWP1921_Wave_Config g_Wave_Config[AWP1912_SLICE_NUMBER_MAX] =
{
    {   //slice0
        AWP1921_SLICE_NUMBER_0,
        AWP1912_SLICE0_START_ADDR,
        AWP1912_SLICE0_400_POINTS,
        AWP1921_LOOP_30_TIME,
        AWP1921_ENDLESS_DISABLE,
        AWP1921_SRAM_PLAY,
        g_slice0_start_addr_0x0004_60V_400point_sinc
    },
    {   //slice1
        AWP1921_SLICE_NUMBER_1,
        AWP1912_SLICE1_START_ADDR,
        AWP1912_SLICE1_400_POINTS,
        AWP1921_LOOP_30_TIME,
        AWP1921_ENDLESS_DISABLE,
        AWP1921_SENSE_PLAY,
        g_slice1_start_addr_0x0200_60V_400point_gauss
    }
};

void AWP1921_I2C_Init(void)
{
    I2C_Handle.Instance           = I2C1;
    I2C_Handle.Init.I2C_Mode      = I2C_MODE_MASTER;
    I2C_Handle.Init.Tx_Auto_En    = TX_AUTO_ENABLE;
    I2C_Handle.Init.Clock_Speed   = CLOCK_SPEED_STANDARD;
    I2C_Handle.Init.Stretch_Mode  = STRETCH_MODE_DISABLE;
    I2C_Handle.Init.filter_enable = FILTER_ALGO_DISABLE;

    HAL_I2C_Init(&I2C_Handle);

}

/* 8bit 寄存器地址 16bit 寄存器值 */
void AWP1921_I2C_Write_REG(uint8_t regAddr, uint16_t regVal)
{
    HAL_StatusTypeDef status;
    uint8_t txBuffer[3] = {0};

    txBuffer[0] = regAddr;
    txBuffer[1] = (regVal >> 8) & 0xff;
    txBuffer[2] = regVal & 0xff;

    status = HAL_I2C_Master_Transmit(&I2C_Handle, AWP1921_DEV_ADDRESS, txBuffer, 3, 0);
    if (status != HAL_OK) {
        printf("awp1921 i2c write regaddr: 0x%02x regval: 0x%04x failed \r\n", regAddr, regVal);
    }

}

/* 8bit 寄存器地址 16bit 寄存器值 */
void AWP1921_I2C_Read_REG(uint8_t regAddr, uint16_t *regVal)
{
    HAL_StatusTypeDef status;
    uint8_t txBuffer[3] = {0};
    uint8_t rxBuffer[3] = {0};

    txBuffer[0] = regAddr;

    /* i2c协议比较特殊， 需要不带stop信号 */
    status = HAL_AWP1921_I2C_Master_Transmit_Without_Stop(&I2C_Handle, AWP1921_DEV_ADDRESS, txBuffer, 1, 0);
    if (status != HAL_OK) {
        printf("%s:%d: awp1921 i2c read  regaddr: 0x%02x failed  \r\n",__FILE__, __LINE__, regAddr);
    }

    status = HAL_I2C_Master_Receive(&I2C_Handle, AWP1921_DEV_ADDRESS, rxBuffer, 2, 0);
    if (status != HAL_OK) {
        printf("%s:%d: awp1921 i2c read  regaddr: 0x%02x failed  \r\n", __FILE__, __LINE__, regAddr);
    }
    *regVal = ((rxBuffer[0] << 8) & 0xff00) | (rxBuffer[1] & 0xff);
}

/* 批量连续写数据 */
void AWP1921_I2C_Write_Date(uint8_t regAddr, uint8_t *data, uint16_t dataLen)
{
    HAL_StatusTypeDef status;
    uint8_t txBuffer[AWP1921_SRAM_BUFFER_LEN+1] = {0};

    txBuffer[0] = regAddr;
    memcpy(txBuffer + 1, data, dataLen);

    status = HAL_I2C_Master_Transmit(&I2C_Handle, AWP1921_DEV_ADDRESS, txBuffer, dataLen + 1, 0);
    if (status != HAL_OK) {
        printf("awp1921 i2c write data failed \r\n");
    }
}

/* amplitude_MV 表示振幅电压单位毫伏
   dacSmpleRate 表示：1个码字播放的时间=1+dacSmpleRate (us)
*/
static void AWP1921_SET_DAC_Common_Config2(void)
{
    uint8_t outVpk = 0u;
    uint16_t regVal = 0u;

    AWP1921_I2C_Read_REG(AWP1921_REG_ADDR_14, &regVal);

    outVpk = (uint8_t)((g_Common_Config.amplitude_MV / 2970) - 1); /* amplitude_MV =2970 *(1+outVpk) */

    regVal = regVal | ((outVpk & 0x1f) << 2); /* 与0x3c表示 outVpk 只有6位*/
    AWP1921_I2C_Write_REG(AWP1921_REG_ADDR_14, regVal);
    AWP1921_I2C_Write_REG(AWP1921_REG_ADDR_15, g_Common_Config.dacSampleRate);
}

/* adcGainScale:   false表示 95V 量程进行量化, true 表示 19V 量程进行量化
   adcPol:    false表示 ADC使用OUT+进行量化, true 表示 ADC使用OUT-进行量化
   adcCalibeEnable: true表示 开启ADC校准， false 表示关闭ADC校准；注意按钮事件一定要开启ADC校准
*/
static void AWP1921_SET_ADC_Common_Config(void)
{
    uint16_t regVal = 0u;

    AWP1921_I2C_Read_REG(AWP1921_REG_ADDR_0B, &regVal);

    if (g_Common_Config.adcGainScale == AWP1921_ADC_GAIN_FULL_SCALE_19V) {
        regVal = regVal | (0x0001u << 9);
    } else {
        regVal = regVal & (~(0x0001u << 9));
    }
    if (g_Common_Config.adcPol == AWP1921_ADC_OUT_NEGATIVE_POLARITY) {
        regVal = regVal | (0x0001u << 8);
    } else {
        regVal = regVal & (~(0x0001u << 8));

    }
    AWP1921_I2C_Write_REG(AWP1921_REG_ADDR_0B, regVal);

    if (g_Common_Config.adcCalibeEnable == AWP1921_ADC_CALIBE_ENABLE) {
        AWP1921_I2C_Write_REG(AWP1921_REG_ADDR_0A, 0x8000);
    } else {
        AWP1921_I2C_Write_REG(AWP1921_REG_ADDR_0A, 0x0000);
    }
}

/* wave表示输出波形的数组 */
static void AWP1921_Download_Sram_Data(const uint16_t *wave, uint16_t waveLen)
{
    uint8_t dataBuf[AWP1921_SRAM_BUFFER_LEN] = {0};
    uint16_t i = 0;
    /* 由于波形数据是16bit, 需要转化为8bit的数据形式进行I2C传输 */

    //printf("wave[0] 0x%04x  wave[1] 0x%04x \r\n", wave[0], wave[1]);
    for (i = 0u; i < waveLen; i++) {
        dataBuf[i * 2] = (wave[i] >> 8) & 0xff;
        dataBuf[i * 2 + 1] = (wave[i + 1] >> 8) & 0xff;
    }
    AWP1921_I2C_Write_Date(AWP1921_REG_ADDR_00, dataBuf, waveLen * 2);
    HAL_Delay(1);
}

static void AWP1921_Download_SRAM_Wave(void)
{
    uint8_t i = 0u;
    uint16_t regVal = 0u;

    AWP1921_I2C_Read_REG(AWP1921_REG_ADDR_14, &regVal);
    regVal = (regVal & 0xfffc) | 0x0003; // SRAM读写模式
    AWP1921_I2C_Write_REG(AWP1921_REG_ADDR_14, regVal);

    for (i = 0u; i < AWP1912_SLICE_NUMBER_MAX; i++) {
        AWP1921_I2C_Write_REG(AWP1921_REG_ADDR_16, g_Wave_Config[i].waveNumber << 1); //slice n数据，则往 0x16 寄存器写入的值为 2*n
        AWP1921_I2C_Write_REG(AWP1921_REG_ADDR_00, g_Wave_Config[i].startAddr);
        AWP1921_I2C_Write_REG(AWP1921_REG_ADDR_00, g_Wave_Config[i].startAddr + g_Wave_Config[i].waveLen);
        AWP1921_I2C_Write_REG(AWP1921_REG_ADDR_16, g_Wave_Config[i].startAddr);
        AWP1921_Download_Sram_Data(g_Wave_Config[i].wavebuf,   g_Wave_Config[i].waveLen);
    }

    AWP1921_I2C_Read_REG(AWP1921_REG_ADDR_14, &regVal);
    regVal = (regVal & 0xfffc) | 0x0002; // RAM播放模式
    AWP1921_I2C_Write_REG(AWP1921_REG_ADDR_14, regVal);

}


void AWP1921_Sense_EnablePlay_Or_Stop(AWP1921_BOOL enblePlay)
{
    uint16_t regVal = 0u;


    AWP1921_I2C_Write_REG(AWP1921_REG_ADDR_06, 0x0001); //开启 adc 采样

    if (enblePlay == AWP1921_ENABLE_SENSE_PLAY) {
        if (g_Sensor_Play_Config0.eventType == AWP1921_ADC_OVER_H_EN) {
            regVal = (AWP1921_ADC_EVENT_ENABLE << 15) | (g_Wave_Config[g_Sensor_Play_Config0.waveNumber].endless << 14)
                | (g_Wave_Config[g_Sensor_Play_Config0.waveNumber].loopTime << 5) | g_Sensor_Play_Config0.waveNumber;

            AWP1921_I2C_Write_REG(AWP1921_REG_ADDR_0D, regVal);

        } else if (g_Sensor_Play_Config0.eventType == AWP1921_ADC_OVER_H_NEGEDGE_EN) {
            regVal = (AWP1921_ADC_EVENT_ENABLE << 15) | (g_Wave_Config[g_Sensor_Play_Config0.waveNumber].endless << 14)
                | (g_Wave_Config[g_Sensor_Play_Config0.waveNumber].loopTime << 5) | g_Sensor_Play_Config0.waveNumber;

            AWP1921_I2C_Write_REG(AWP1921_REG_ADDR_10, regVal);
        }
    } else {
        if (g_Sensor_Play_Config0.eventType == AWP1921_ADC_OVER_H_EN) {
            AWP1921_I2C_Write_REG(AWP1921_REG_ADDR_0D, 0x0000);

        } else if (g_Sensor_Play_Config0.eventType == AWP1921_ADC_OVER_H_NEGEDGE_EN) {
            AWP1921_I2C_Write_REG(AWP1921_REG_ADDR_10, 0x0000);
        }
    }
}


void AWP1921_SRAM_Play_Or_Stop(AWP1921_SRAM_Play_Type sramPlayType)
{
    uint16_t regVal = 0u;
    switch (sramPlayType) {
        case AWP1921_SRAM_LONG_PLAY:
             g_Wave_Config[AWP1921_SLICE_NUMBER_0].loopTime = AWP1921_LOOP_90_TIME;
            break;
        case AWP1921_SRAM_MIDIUM_PLAY:
            g_Wave_Config[AWP1921_SLICE_NUMBER_0].loopTime = AWP1921_LOOP_60_TIME;

            break;
        case AWP1921_SRAM_SHORT_PLAY:
            g_Wave_Config[AWP1921_SLICE_NUMBER_0].loopTime = AWP1921_LOOP_30_TIME;

            break;
        case AWP1921_SRAM_NO_PLAY:
            AWP1921_I2C_Write_REG(AWP1921_REG_ADDR_13, 0x0000);
            break;
        defualt:
            AWP1921_I2C_Write_REG(AWP1921_REG_ADDR_13, 0x0000);
            break;
    }

    if (sramPlayType == AWP1921_SRAM_NO_PLAY) {
        AWP1921_I2C_Write_REG(AWP1921_REG_ADDR_13, 0x0000);
        AWP1921_I2C_Write_REG(AWP1921_REG_ADDR_06, 0x0008); //停止 play 播放
	    //AWP1921_I2C_Write_REG(AWP1921_REG_ADDR_06, 0x0001); //开启 adc 采样
    } else {
        regVal = (g_Wave_Config[AWP1921_SLICE_NUMBER_0].waveNumber)
            | (g_Wave_Config[AWP1921_SLICE_NUMBER_0].loopTime << 5)
            | (g_Wave_Config[AWP1921_SLICE_NUMBER_0].endless << 14);
        AWP1921_I2C_Write_REG(AWP1921_REG_ADDR_13, regVal);
        AWP1921_I2C_Write_REG(AWP1921_REG_ADDR_06, 0x0004); //play 播放
	    //AWP1921_I2C_Write_REG(AWP1921_REG_ADDR_06, 0x0001); //开启 adc 采样
    }

}



static void AWP1921_Set_Sense_Play_Config(void)
{
    AWP1921_I2C_Write_REG(AWP1921_REG_ADDR_0D, 0x0000);
    AWP1921_I2C_Write_REG(AWP1921_REG_ADDR_0E, 0x0000);
    AWP1921_I2C_Write_REG(AWP1921_REG_ADDR_0F, 0x0000);
    AWP1921_I2C_Write_REG(AWP1921_REG_ADDR_10, 0x0000);
    AWP1921_I2C_Write_REG(AWP1921_REG_ADDR_11, 0x0000);
    AWP1921_I2C_Write_REG(AWP1921_REG_ADDR_12, 0x0000);

    AWP1921_Sense_EnablePlay_Or_Stop(AWP1921_SENSE_STOP_PLAY);
}

static void AWP1921_Set_ADC_Config(void)
{
    uint16_t regVal = 0u;

    AWP1921_I2C_Write_REG(AWP1921_REG_ADDR_06, 0x0008); //stop play 播放
    AWP1921_I2C_Write_REG(AWP1921_REG_ADDR_06, 0x0002); //停止 adc 采样

    if (g_ADC_Config.senseCfg[0].eventType == AWP1921_ADC_OVER_H_EN) {
        AWP1921_I2C_Write_REG(AWP1921_REG_ADDR_03, 0x20f0); //使能ADC OVER_H事件触发INRT脚拉低
    } else if (g_ADC_Config.senseCfg[0].eventType == AWP1921_ADC_OVER_H_NEGEDGE_EN) {
        AWP1921_I2C_Write_REG(AWP1921_REG_ADDR_03, 0x04f0); //使能ADC OVER_H_POSEDEGE事件触发INRT脚拉低
    }

    AWP1921_I2C_Read_REG(AWP1921_REG_ADDR_0B, &regVal);
    regVal = (regVal &0xfffc) | g_ADC_Config.adcMode;
    AWP1921_I2C_Write_REG(AWP1921_REG_ADDR_0B, regVal);

    regVal = (g_ADC_Config.adcAverageTime << 4) | g_ADC_Config.adcOvvTime;
    AWP1921_I2C_Write_REG(AWP1921_REG_ADDR_0C, regVal);


    AWP1921_I2C_Write_REG(AWP1921_REG_ADDR_08, g_ADC_Config.adcThresholdHigh);
    //AWP1921_I2C_Write_REG(AWP1921_REG_ADDR_09, config->adcThresholdLow);

    AWP1921_Set_Sense_Play_Config();

    AWP1921_I2C_Write_REG(AWP1921_REG_ADDR_06, 0x0001); //开启 adc 采样
}



void AWP1921_Init(void)
{
    uint16_t regVal = 0u;
    AWP1921_I2C_Init();
    HAL_Delay(100);
    AWP1921_I2C_Write_REG(AWP1921_REG_ADDR_01, 0x5F76);
    HAL_Delay(100);
    regVal = AWP1921_Read_Status();
    printf("AWP1921_Init reg:02 val: 0x%04x \r\n",  regVal);

    AWP1921_SET_ADC_Common_Config();
    AWP1921_SET_DAC_Common_Config2();
    AWP1921_Download_SRAM_Wave();
    AWP1921_Set_ADC_Config();
}


uint16_t AWP1921_Read_ADC_Date(void)
{
    uint16_t regVal = 0u;
    AWP1921_I2C_Read_REG(AWP1921_REG_ADDR_07, &regVal);
    return regVal;
}

uint16_t AWP1921_Read_Status(void)
{
    uint16_t regVal = 0u;
    AWP1921_I2C_Read_REG(AWP1921_REG_ADDR_02, &regVal);
    return regVal;
}



